home *** CD-ROM | disk | FTP | other *** search
- #
- # (C) Tenable Network Security
- #
- # script audited and subsequently patched thanks to submission by Bert Salaets
-
- if(description) {
- script_id(11935);
- script_version("$Revision: 1.5 $");
-
- name["english"] = "IPSEC IKE detection";
- script_name(english:name["english"]);
-
- desc["english"] =
- "The remote host seems to be enabled to do Internet Key
- Exchange (IKE). This is typically indicative of a VPN server.
- VPN servers are used to connect remote hosts into internal
- resources.
-
- Solution: You should ensure that:
- 1) The VPN is authorized for your Companies computing environment
- 2) The VPN utilizes strong encryption
- 3) The VPN utilizes strong authentication
-
- Risk factor : Low";
-
- script_description(english:desc["english"]);
-
- summary["english"] = "IPSEC IKE detect";
- script_summary(english:summary["english"]);
-
- script_category(ACT_GATHER_INFO);
-
- script_copyright(english:"This script is Copyright (C) 2003 Tenable Network Security");
- family["english"] = "General";
- script_family(english:family["english"]);
- exit(0);
- }
-
- #
- # The script code starts here
- #
-
-
- function calc_data() {
- T_PAY1 = T_NP + T_RES + T_PLEN + T_NUM + T_ID + T_RES2 + T_FLAGS + T_AC + T_AV + T_FLAGS2 + T_AC2 + T_AV2 + T_FLAGS3
- + T_AC3 + T_AV3 + T_FLAGS4 + T_AC4 + T_AV4 + T_FLAGS5 + T_AC5 + T_AV5 + T_FLAGS6 + T_AC6 + T_ALEN + T_AV6;
-
- for (MU=2; MU < TRANSFORM_MAX; MU++) {
-
- TPAY[MU] = T_NP + T_RES + T_PLEN + raw_string(MU) + T_ID + T_RES2 + T_FLAGS + T_AC + T_AV + T_FLAGS2 + T_AC2 + T_AV2 + T_FLAGS3 + T_AC3 + T_AV3 + T_FLAGS4 + T_AC4 + T_AV4 + T_FLAGS5 + T_AC5 + T_AV5 + T_FLAGS6 + T_AC6 + T_ALEN + T_AV6;
-
- }
-
- TPAY[MU] = raw_string(0x00) + T_RES + T_PLEN + raw_string(MU) + T_ID + T_RES2 + T_FLAGS + T_AC + T_AV + T_FLAGS2 + T_AC2 + T_AV2 + T_FLAGS3 + T_AC3 + T_AV3 + T_FLAGS4 + T_AC4 + T_AV4 + T_FLAGS5 + T_AC5 + T_AV5 + T_FLAGS6 + T_AC6 + T_ALEN + T_AV6;
-
-
- tmp = (MU * T_PAY_SZ) + strlen(IC) + strlen(RC) + strlen(NP) + strlen(MV) + strlen(ET) + strlen(IF) + strlen(MI) + 4;
-
- tmp = tmp + SA_HEADER_SZ + PROP_HEADER_SZ; # sizeof SA_HEADER + PROP_HEADER
- myplen = tmp - 28;
- myp_plen = myplen - 12;
-
- len4 = tmp / 0xFFFFFF;
- len3 = tmp / 0xFFFF;
- len2 = tmp / 0xFF;
- len1 = tmp % 256;
- LEN=raw_string(len4,len3,len2,len1);
-
- len2 = myplen / 0xFF;
- len1 = myplen % 256;
- PLEN=raw_string(len2, len1);
-
- len2 = myp_plen / 0xFF;
- len1 = myp_plen % 256;
- P_PLEN=raw_string(len2, len1);
-
- SA_HEADER = SA_NP + RES + PLEN + DOI + SIT;
-
- PROP_HEADER = P_NP + P_RES + P_PLEN + P_NUM + PID + SPI_SZ + T_NUM_TOT;
-
- ISAKMP_HEADER = IC + RC + NP + MV + ET + IF + MI + LEN;
-
- blap = ISAKMP_HEADER + SA_HEADER + PROP_HEADER + T_PAY1;
- for (MU=2; MU <= TRANSFORM_MAX; MU++) {
- blap = blap + TPAY[MU];
- }
-
- return(blap);
- }
-
-
-
-
-
- srcaddr = this_host();
- dstaddr = get_host_ip();
- port = 500;
- srcport = rand() % 65535;
-
- if(!get_udp_port_state(port))exit(0);
-
-
-
- #------ISAKMP header-----#
-
- IC = raw_string (0xFF, 0x00, 0xFE, 0x01, 0xFD, 0x02, 0xFC, 0x03); #8 byte Initiator cookie
- RC = raw_string (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); #8 byte Responder cookie
-
- NP = raw_string (0x01); #Next payload = 1 = Security Association
- # 2 = proposal / 3 = transform / 4 = Key exchange
- # 5 = ID / 6 = CERT / 7 = Cert request
- # 8 = HASH / 9 = SIGNATURE / 10 = NONCE
- # 11 = Notification / 12 = Delete
- # 13 = Vendor ID / 14-27 = RESERVED
- # 128-255 = PRIVATE USE
-
-
- MV = raw_string (0x10); # 4bits = Major version
- # 4 low order bits = Minor version
-
-
- ET = raw_string (0x02); # Exchange type = 4 = AGGRESSIVE
- # 0 = NONE / 1 = BASE / 2 = Identity protection
- # 3 = Authentication only / 5 = Informational
- # 6-31 = FUTURE USE / 32-239 = DOI use
- # 240-255 = Private use
-
- IF = raw_string (0x00);
- MI = raw_string(0x00,0x00,0x00,0x00); # Message ID
- #LEN = raw_string (0x00,0x00,0x01,0x7b); # Length = total length of UDP data field
-
-
- #ISAKMP_HEADER = IC + RC + NP + MV + ET + IF + MI + LEN;
- ISAKMP_HEADER_SZ = 28;
-
-
-
-
-
- # ----- Security Association ---------#
-
- SA_NP = raw_string(0x00); # Security Association next payload = key exchange
- RES = raw_string(0x00); # reserved
- PLEN = raw_string(0x00,0x80); # Security association payload length = LEN - 28
- # total len of all payloads (through last TP) + 12
- DOI = raw_string(0x00,0x00,0x00,0x01); # DOI = generic ISAKMP Security Association
- SIT = raw_string(0x00,0x00,0x00,0x01); # Situation
-
- SA_HEADER = SA_NP + RES + PLEN + DOI + SIT;
- SA_HEADER_SZ = 12;
-
-
-
-
-
-
- # ------Proposal --------------------#
-
- P_NP = raw_string(0x00); # Proposal next payload = 0 (last proposal payload)
- P_RES = raw_string(0x00); # reserved
- P_PLEN = raw_string(0x00,0x74); # Proposal payload length = LEN - 40
- # payloads through last TP
- P_NUM = raw_string(0x01); # proposal number
- PID = raw_string(0x01); # protocol ID = 1 = proto_isakmp
- SPI_SZ = raw_string(0x00); # SPI size
- T_NUM_TOT = raw_string(0x08); # number of transforms
-
- PROP_HEADER = P_NP + P_RES + P_PLEN + P_NUM + PID + SPI_SZ + T_NUM_TOT;
- PROP_HEADER_SZ = 8;
-
-
-
-
-
-
- # -----Transform Payload ------------#
- T_NP = raw_string(0x03); # transform next payload = 3 = more transforms
- T_RES = raw_string(0x00); # reserved
- T_PLEN = raw_string(0x00,0x24); # payload length -- 36 bytes per transform
- T_NUM = raw_string(0x01); # transform number
- T_ID = raw_string(0x01); # transform ID
- T_RES2 = raw_string(0x00,0x00); # reserved
- T_FLAGS = raw_string(0x80); # data attribute following TV format
- T_AC = raw_string(0x01); # Attribute type/class = 1 encryption alg basic
- T_AV = raw_string(0x00,0x05); # Transform attribute value = 3des_CBC
- T_FLAGS2 = raw_string(0x80);
- T_AC2 = raw_string(0x02); # attribute type/class = 2 = hash alg basic
- T_AV2 = raw_string(0x00,0x02); # attribute value = 2 = SHA
- T_FLAGS3 = raw_string(0x80);
- T_AC3 = raw_string(0x03); # attribute type/class = 4 = group description basic
- T_AV3 = raw_string(0x00,0x01); # attribute value = 2 = alternate 1024 bit MODP group
- T_FLAGS4 = raw_string(0x80);
- T_AC4 = raw_string(0x04); # attribute type/class = 3 = basic authentication
- T_AV4 = raw_string(0x00,0x02); # attribute value = 65001 = for private use
- T_FLAGS5 = raw_string(0x80);
- T_AC5 = raw_string(0x0b); # attribute type/class = 11 = basic life type
- T_AV5 = raw_string(0x00,0x01); # attribute value = 1 = life duration in seconds
- T_FLAGS6 = raw_string(0x00);
- T_AC6 = raw_string(0x0c); # attribute type/class = 12 = variable life duration
- T_ALEN = raw_string(0x00,0x04); # attribute length = 4 bytes
- T_AV6 = raw_string(0x00,0x20,0xC4,0x9B); # attribute value
-
- T_PAY_SZ = 36;
-
- T_PAY1 = T_NP + T_RES + T_PLEN + T_NUM + T_ID + T_RES2 + T_FLAGS + T_AC + T_AV + T_FLAGS2 + T_AC2 + T_AV2 + T_FLAGS3 +
- T_AC3 + T_AV3 + T_FLAGS4 + T_AC4 + T_AV4 + T_FLAGS5 + T_AC5 + T_AV5 + T_FLAGS6 + T_AC6 + T_ALEN + T_AV6;
-
-
-
-
-
-
-
- # -----Transform Payloads 2 and up -----------#
- # nothing changes except transform number .... and "Next payload" (on last payload)
-
- TRANSFORM_MAX = 8;
-
- for (TPAYRRAY=2; TPAYRRAY < TRANSFORM_MAX; TPAYRRAY++) {
-
- TPAY[TPAYRRAY] = T_NP + T_RES + T_PLEN + raw_string(TPAYRRAY) + T_ID + T_RES2 + T_FLAGS + T_AC + T_AV + T_FLAGS2 + T_AC2 + T_AV2 + T_FLAGS3 + T_AC3 + T_AV3 + T_FLAGS4 + T_AC4 + T_AV4 + T_FLAGS5 + T_AC5 + T_AV5 + T_FLAGS6 + T_AC6 + T_ALEN + T_AV6;
- }
-
- TPAY[TPAYRRAY] = raw_string(0x00) + T_RES + T_PLEN + raw_string(TPAYRRAY) + T_ID + T_RES2 + T_FLAGS + T_AC + T_AV + T_FLAGS2 + T_AC2 + T_AV2 + T_FLAGS3 + T_AC3 + T_AV3 + T_FLAGS4 + T_AC4 + T_AV4 + T_FLAGS5 + T_AC5 + T_AV5 + T_FLAGS6 + T_AC6 + T_ALEN + T_AV6;
-
-
-
-
-
- #--------end Proposal Payload ------------------------#
-
- #--------end Security Association Payload-------------#
-
-
-
-
-
- # added this blurb in order to handle racoon which doesn't like
- # Exchange type set to BASIC
- # --------------------------------------------
-
- blat = calc_data();
- soc = open_sock_udp(port);
- if (!soc) exit(0);
- send (socket:soc, data:blat);
- r = recv(socket:soc, length:48, timeout:2);
- rlen = strlen(r);
-
- if (rlen > 16) {
- if ( (ord(r[16]) == 0x01) && (ord(r[18]) == 0x02) ) { security_warning(port, protocol:"udp"); exit(0); }
- if ( (ord(r[16]) == 0x0B) && (ord(r[18]) == 0x05) ) { security_warning(port, protocol:"udp"); exit(0); }
- # still here?
- mywarning = string("The remote host answers on port 500 UDP\n");
- mywarning += string("If you know what the host is running, please send the\n");
- # maybe need an address like ike-fingerprint@nessus.org????
- mywarning += string("version as well as the following text to jwlampe@nessus.org : \n\n");
- for (i=0; i<rlen; i++) {
- mywarning = mywarning + (string(ord(r[i]), " "));
- }
- security_warning(port, protocol:"udp");
- exit(0);
- }
-
- # end racoon check ---------------------------
-
-
-
- # now handle non-racoon IPSEC ;-)
- ET = raw_string(0x01); # change exchange type to BASIC
- MV = raw_string(0xFF); # set Major version = minor version = 15 (obviously bogus)
- # this *should* generate an error reply
-
-
- blat = calc_data();
-
-
- soc = open_sock_udp(port);
- if (!soc) exit(0);
- send (socket:soc, data:blat);
- r = recv(socket:soc, length:48, timeout:2);
- rlen = strlen(r);
- if (rlen > 16) {
- if ( (ord(r[16]) == 0x0B) && (ord(r[18]) == 0x05) ) security_warning(port, protocol:"udp");
- } else {
- #nudge packet didn't work...We'll have to do a little more...
- # why this check, you might ask????
- # well, some implementations of IPSEC (Microsoft,...) will receive a packet from src port != 500 and dst port=500
- # and reply from src port == 500 dst port == 500
-
-
- blat = calc_data();
- oneoff = strlen(blat);
- filter = string("udp and src host ", get_host_ip(), " and dst host ", this_host(), " and dst port ", port);
- ip = forge_ip_packet( ip_v : 4,
- ip_hl : 5,
- ip_tos : 0,
- ip_len : 20,
- ip_id : 0xABBA,
- ip_p : IPPROTO_UDP,
- ip_ttl : 255,
- ip_off : 0,
- ip_src : this_host(),
- ip_dst : get_host_ip());
-
-
- udpip = forge_udp_packet( ip : ip,
- uh_sport : srcport,
- uh_dport : 500,
- uh_ulen : oneoff + 8,
- data : blat);
-
- live = send_packet(udpip, pcap_active:TRUE, pcap_filter:filter);
- myrep = string("The remote host seems to be enabled to do Internet Key
- Exchange. This is typically indicative of a VPN server.
- VPN servers are used to connect remote hosts into internal
- resources. In addition, The remote host seems to be configured
- to force all communications across port 500 for both the source and
- destination port. That is, we sent the machine a packet from a random
- port greater than 1024. The machine sent the reply back to port 500.
-
- NOTE: This sort of behavior has been observed on Microsoft machines.
-
- Solution: You should ensure that:
- 1) The VPN is authorized for your Companies computing environment
- 2) The VPN utilizes strong encryption
- 3) The VPN utilizes strong authentication
-
- Risk factor : Low");
- if (live) {
- if ( (ord(live[44]) == 0x0B) && (ord(live[46]) == 0x05) ) security_warning(port:port, data:myrep, proto:"udp");
- }
- }
-
- exit(0);
-
-